// @Plugin : DeathRunFix - For Temple of the Moon Corpse Run
// @Author : Onsit
// @Version : 1
// @Date : 4/20/2014

using Styx;
using Styx.Common;
using Styx.Common.Helpers;
using Styx.CommonBot;
using Styx.Pathing;
using Styx.Plugins;
using Styx.TreeSharp;
using Styx.WoWInternals;
using Styx.WoWInternals.WoWObjects;

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Windows.Media;

using CommonBehaviors.Actions;
using Action = Styx.TreeSharp.Action;

namespace DeathRunFix
{
    public class DeathRunFix : HBPlugin
    {
        private static LocalPlayer Me { get { return StyxWoW.Me; } }

        public override string Name { get { return "DeathRunFix - Tol'vir"; } }
        public override string Author { get { return "Onsit"; } }
        public override Version Version { get { return new Version(1, 0); } }
        public override bool WantButton { get { return true; } }
        public override string ButtonText { get { return "DeathRunFix - Tol'vir"; } }
        public override void OnButtonPress() { }
        public static void OGlog(string message, params object[] args) { Logging.Write(Colors.DeepSkyBlue, "[DeathRunFix]: " + message, args); }
        private Composite _hookedCorpseRun;
        private bool _Initialized;

        private void BotEvent_OnBotStarted(EventArgs args) { Initialize(); }
        private void BotEvent_OnBotStopped(EventArgs args) { Dispose(); }

        public override void Initialize()
        {
            _hookedCorpseRun = null;
            if (_Initialized) return;
            _Initialized = true;
            BotEvents.OnBotStarted += BotEvent_OnBotStarted;
            BotEvents.OnBotStopped += BotEvent_OnBotStopped;
        }

        public override void Dispose()
        {
            OGlog("unHooked");
            TreeHooks.Instance.RemoveHook("Death_CorpseRun", _hookedCorpseRun);
            _hookedCorpseRun = null;
        }

        public override void Pulse()
        {
            if (_Initialized && _hookedCorpseRun == null && isDead && !_isBehaviorDone && nearMoonTemple)
            {
                OGlog("Hooked");
                _hookedCorpseRun = CreateBehaviorCorpseRun();
                TreeHooks.Instance.ReplaceHook("Death_CorpseRun", _hookedCorpseRun);
            }

            if (!isDead)
            {
                _isBehaviorDone = false;
            }
        }

        private bool _isBehaviorDone = false;
        private Queue<WoWPoint> _pathToDest = null;
        private Composite CreateBehaviorCorpseRun()
        {
            return new PrioritySelector(
                    new Decorator(ret => (_pathToDest == null),
                       new Action(delegate
                       {
                           _pathToDest = new Queue<WoWPoint>();
                           _pathToDest.Enqueue(new WoWPoint(-10730.74, -1550.357, 35.9071));
                           _pathToDest.Enqueue(new WoWPoint(-10734.54, -1385.231, 54.76054));
							_pathToDest.Enqueue(new WoWPoint(-10647.75, -1299.349, 34.30367));
							_pathToDest.Enqueue(new WoWPoint(-10690.87, -1311.008, 17.79055));
                       })),

                   new Decorator(ret => (Me.Location.Distance(_pathToDest.Peek()) > 3),
                       new Sequence(
                           new Action(delegate { Flightor.MoveTo(_pathToDest.Peek()); })
                       )),

                   new Action(delegate
                   {
                       _pathToDest.Dequeue();
                       if (_pathToDest.Count() > 0)
                       { return (RunStatus.Success); }
                       _isBehaviorDone = true;
                       _pathToDest = null;
                       Dispose();
                       return (RunStatus.Failure);
                   }));
        }

        public bool isDead
        {
            get{
                return Me.IsGhost || Me.IsDead;
            }
        }

        public bool nearMoonTemple
        {
            get
            {
                return (Me.Location.Distance(new WoWPoint(-8814.3, 90.3212, 131.178)) < 3000);
            }
        }
    }
}